package game

import (
	"math"
	"math/rand"
	"server/db"
	"server/game/internal"
	"server/msg"
	"strconv"

	"google.golang.org/protobuf/proto"
	"server/pkg/github.com/name5566/leaf/gate"
)

type PlayerProfileManager struct {
	MsqlStrucks []db.SqlPlayerProfileStruct
	MapSql      map[int32]*db.SqlPlayerProfileStruct
}

func (p *PlayerProfileManager) LoadDataFromDB(dwUin interface{}) bool {

	sqlStr := "SELECT * FROM t_player_Profile_Data"
	p.MsqlStrucks = []db.SqlPlayerProfileStruct{}
	p.MapSql = make(map[int32]*db.SqlPlayerProfileStruct)
	db.SqlDb.Select(&p.MsqlStrucks, sqlStr)

	for i := 0; i < len(p.MsqlStrucks); i++ {
		item := p.MsqlStrucks[i]
		p.MapSql[item.DwUin] = &item
	}

	return true
}

func (p *PlayerProfileManager) GetPlayerDecorate(dwUin int32) (int, int, string) {
	sqlStr := "SELECT * FROM t_player_baseinfo WHERE dwUin = ?"
	sqlStruck := db.ResPlayerBaseInfo{}
	decorate := 0
	ActiveTime := 0
	FaceBookId := ""
	if err := db.SqlDb.Get(&sqlStruck, sqlStr, dwUin); err != nil {

	} else {
		Score := 0
		for i := 1; i < int(sqlStruck.Level); i++ {
			Score = Score + (i-1)*10 + 20
		}
		Score = Score + int(sqlStruck.Exp)
		decorate = Score / 10
		ActiveTime = int(math.Max(float64(sqlStruck.LoginTime), float64(sqlStruck.LogoutTime)))
		FaceBookId = sqlStruck.FaceBookId
	}
	return decorate, ActiveTime, FaceBookId
}

func (p *PlayerProfileManager) InitManager() {
	p.LoadDataFromDB("")
}

func (p *PlayerProfileManager) AddNewProfile(st *db.SqlPlayerProfileStruct) bool {
	if p.GetPlayerProfile(st.DwUin) == nil {
		p.MapSql[st.DwUin] = st
		db.FormatAllMemInsertDb(st, "t_player_Profile_Data")
	}
	return true
}

func (p *PlayerProfileManager) UpdateNewProfile(st *db.SqlPlayerProfileStruct) bool {
	if p.GetPlayerProfile(st.DwUin) != nil {
		p.MapSql[st.DwUin] = st
		db.FormatAllMemUpdateDb(st, "t_player_Profile_Data", "dwUin")
	} else {
		p.AddNewProfile(st)
	}
	return true
}

func (p *PlayerProfileManager) GetPlayerProfileByNick(nick string) []*db.SqlPlayerProfileStruct {
	ret := []*db.SqlPlayerProfileStruct{}
	// G_getGameLogic().Mlogger.Debug("p.MapSql" + strconv.Itoa(len(p.MapSql)))
	// G_getGameLogic().Mlogger.Debug("nick:" + nick)
	for k, v := range p.MapSql {
		if strconv.Itoa(int(k)) == nick {
			ret = append(ret, v)
		} else {
			// G_getGameLogic().Mlogger.Debug("v.NickName:" + v.NickName)
			if nick == v.NickName {
				ret = append(ret, v)
			}
		}
	}
	return ret
}

func (p *PlayerProfileManager) GetPlayerProfile(id int32) *db.SqlPlayerProfileStruct {

	st, ok := p.MapSql[id]
	if ok {
		return st
	}
	return nil
}
func (p *PlayerProfileManager) GetIsHavePlayerById(id int32) bool {
	sqlStr := "SELECT * FROM t_player_baseinfo WHERE dwUin = ?"
	sqlStruck := db.ResPlayerBaseInfo{}
	if err := db.SqlDb.Get(&sqlStruck, sqlStr, id); err != nil {

	} else {
		return true
	}
	return false
}

func (p *PlayerProfileManager) ReqPlayerProfileData(args []interface{}) {
	a := args[0].(gate.Agent)
	play, _ := internal.Agents[a]
	buf := args[1].([]byte)
	player := play.(*Player)

	req := &msg.ReqPlayerProfileData{}
	res := &msg.ResPlayerProfileData{}
	proto.Unmarshal(buf, req)
	profile := p.GetPlayerProfile(player.M_DwUin)
	if profile != nil {
		res.DwUin = player.M_DwUin
		res.NickName = profile.NickName
		res.ImageFrame = profile.ImageFrame
		res.ImageIcon = profile.ImageIcon
		res.PicURL = profile.PicURL
		res.UnlockFrame = profile.UnlockFrame
		res.UnlockIcon = profile.UnlockIcon
		DecorateCnt, ActiveTime, _ := p.GetPlayerDecorate(player.M_DwUin)
		res.DecorateCnt = int32(DecorateCnt)
		res.ActiveTime = int32(ActiveTime)
	} else {
		res.DwUin = player.M_DwUin
		res.NickName = "Player" + strconv.Itoa(int(player.M_DwUin))
		res.ImageFrame = 1
		res.ImageIcon = 1
		res.UnlockFrame = ""
		res.UnlockIcon = ""
		res.PicURL = ""
		DecorateCnt, ActiveTime, _ := p.GetPlayerDecorate(player.M_DwUin)
		res.DecorateCnt = int32(DecorateCnt)
		res.ActiveTime = int32(ActiveTime)

		st := db.SqlPlayerProfileStruct{}
		st.DwUin = player.M_DwUin
		st.ImageFrame = 1
		st.ImageIcon = 1
		st.UnlockFrame = ""
		st.UnlockIcon = ""
		st.PicURL = ""
		st.NickName = "Player" + strconv.Itoa(int(player.M_DwUin))
		p.UpdateNewProfile(&st)
	}
	agent := player.GetAgentByPlayer()
	data1, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResPlayerProfileData", data1)

}

func (p *PlayerProfileManager) ReqUpdatePlayerProfile(args []interface{}) {
	a := args[0].(gate.Agent)
	play, _ := internal.Agents[a]
	buf := args[1].([]byte)
	player := play.(*Player)

	req := &msg.ReqUpdatePlayerProfile{}
	res := &msg.ResUpdatePlayerProfile{}
	proto.Unmarshal(buf, req)
	profile := p.GetPlayerProfile(player.M_DwUin)
	if profile != nil {
		if req.Type == 1 {
			profile.NickName = req.Param
		}
		if req.Type == 2 {
			value, _ := strconv.Atoi(req.Param)
			profile.ImageFrame = int32(value)
		}
		if req.Type == 3 {
			value, _ := strconv.Atoi(req.Param)
			profile.ImageIcon = int32(value)
		}
		p.UpdateNewProfile(profile)
	} else {
		st := db.SqlPlayerProfileStruct{}
		st.DwUin = player.M_DwUin
		st.ImageFrame = 1
		st.ImageIcon = 1
		st.NickName = "Player" + strconv.Itoa(int(player.M_DwUin))
		if req.Type == 1 {
			st.NickName = req.Param
		}
		if req.Type == 2 {
			value, _ := strconv.Atoi(req.Param)
			st.ImageFrame = int32(value)
		}
		if req.Type == 3 {
			value, _ := strconv.Atoi(req.Param)
			st.ImageIcon = int32(value)
		}
		st.UnlockFrame = ""
		st.UnlockIcon = ""
		st.PicURL = ""
		p.UpdateNewProfile(&st)
	}
	res.DwUin = req.DwUin
	res.Type = req.Type
	res.Param = req.Param
	res.ResultCode = 0
	agent := player.GetAgentByPlayer()
	data1, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResUpdatePlayerProfile", data1)

}

func (p *PlayerProfileManager) HttpReqPlayerBriefProfileData(Id int32) *msg.ResPlayerBriefProfileData {
	profile := p.GetPlayerProfile(Id)
	res := &msg.ResPlayerBriefProfileData{}
	if profile != nil {
		res.DwUin = profile.DwUin
		res.NickName = profile.NickName
		res.ImageFrame = profile.ImageFrame
		res.ImageIcon = profile.ImageIcon
		DecorateCnt, ActiveTime, _ := p.GetPlayerDecorate(Id)
		res.DecorateCnt = int32(DecorateCnt)
		res.ActiveTime = int32(ActiveTime)
		res.PicURL = profile.PicURL
	} else {
		res.DwUin = Id
		res.NickName = "Player" + strconv.Itoa(int(Id))
		res.ImageFrame = 1
		res.ImageIcon = 1
		res.PicURL = ""
		DecorateCnt, ActiveTime, _ := p.GetPlayerDecorate(Id)
		res.DecorateCnt = int32(DecorateCnt)
		res.ActiveTime = int32(ActiveTime)

		st := db.SqlPlayerProfileStruct{}
		st.DwUin = Id
		st.ImageFrame = 1
		st.ImageIcon = 1
		st.UnlockFrame = ""
		st.UnlockIcon = ""
		st.PicURL = ""
		st.NickName = "Player" + strconv.Itoa(int(Id))
		p.UpdateNewProfile(&st)
	}
	return res
}

func (p *PlayerProfileManager) ReqPlayerBriefProfileData(args []interface{}) {
	a := args[0].(gate.Agent)
	play, _ := internal.Agents[a]
	buf := args[1].([]byte)
	player := play.(*Player)

	req := &msg.ReqPlayerBriefProfileData{}
	res := &msg.ResPlayerBriefProfileData{}
	proto.Unmarshal(buf, req)
	profile := p.GetPlayerProfile(req.DwUin)
	if profile != nil {
		res.DwUin = profile.DwUin
		res.NickName = profile.NickName
		res.ImageFrame = profile.ImageFrame
		res.ImageIcon = profile.ImageIcon
		DecorateCnt, ActiveTime, _ := p.GetPlayerDecorate(req.DwUin)
		res.DecorateCnt = int32(DecorateCnt)
		res.ActiveTime = int32(ActiveTime)
		res.PicURL = profile.PicURL
	} else {
		res.DwUin = req.DwUin
		res.NickName = "Player" + strconv.Itoa(int(req.DwUin))
		res.ImageFrame = 1
		res.ImageIcon = 1
		res.PicURL = ""

		DecorateCnt, ActiveTime, _ := p.GetPlayerDecorate(req.DwUin)
		res.DecorateCnt = int32(DecorateCnt)
		res.ActiveTime = int32(ActiveTime)

		st := db.SqlPlayerProfileStruct{}
		st.DwUin = req.DwUin
		st.ImageFrame = 1
		st.ImageIcon = 1
		st.UnlockFrame = ""
		st.UnlockIcon = ""
		st.PicURL = ""
		st.NickName = "Player" + strconv.Itoa(int(req.DwUin))
		p.UpdateNewProfile(&st)
	}
	agent := player.GetAgentByPlayer()
	data1, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResPlayerBriefProfileData", data1)

}

func (p *PlayerProfileManager) RandomGetAnPlayer(origin int32) *db.SqlPlayerProfileStruct {
	idx := rand.Intn(len(p.MsqlStrucks))

	for p.MsqlStrucks[idx].DwUin == origin {
		idx = rand.Intn(len(p.MsqlStrucks))
	}
	Profile := p.GetPlayerProfile(p.MsqlStrucks[idx].DwUin)

	if Profile != nil {
		return Profile
	} else {
		sql := &db.SqlPlayerProfileStruct{}
		sql.DwUin = p.MsqlStrucks[idx].DwUin
		sql.ImageFrame = 1
		sql.ImageIcon = 1
		sql.NickName = "Player" + strconv.Itoa(int(p.MsqlStrucks[idx].DwUin))
		sql.PicURL = ""
		p.UpdateNewProfile(sql)
		return sql
	}
}
func (p *PlayerProfileManager) GetIsHaveAddFriendInfo(sender int32, receive int32) (bool, *db.SqlAddFriendStruct) {
	sqlStr := "SELECT * FROM t_player_Req_add_Friend WHERE SenderId = ? AND ReceiverId = ?"
	sqlStruck := db.SqlAddFriendStruct{}

	if err := db.SqlDb.Get(&sqlStruck, sqlStr, sender, receive); err != nil {
		return false, nil
	} else {
		return true, &sqlStruck
	}
	// return false
}
func (p *PlayerProfileManager) RandomGetPlayers(Cnt int, originId int32, ExcludeList []int32) []*db.SqlPlayerProfileStruct {

	var CurCnt int = 0
	ret := []*db.SqlPlayerProfileStruct{}
	var Loops int = 0
	for {
		Ids := G_GameLogicPtr.DisorderLuaTable(len(p.MsqlStrucks), int(math.Min(float64(len(p.MsqlStrucks)), float64(Cnt))))
		for i := 0; i < len(Ids); i++ {
			IsIll := true
			for j := 0; j < len(ExcludeList); j++ {
				if ExcludeList[j] == p.MsqlStrucks[Ids[i]].DwUin {
					IsIll = false
					break
				}
			}
			if IsIll {
				isHave1, _ := p.GetIsHaveAddFriendInfo(originId, p.MsqlStrucks[Ids[i]].DwUin)
				isHave2, _ := p.GetIsHaveAddFriendInfo(p.MsqlStrucks[Ids[i]].DwUin, originId)

				if !isHave1 && !isHave2 {
					CurCnt += 1
					ret = append(ret, &p.MsqlStrucks[Ids[i]])
					ExcludeList = append(ExcludeList, p.MsqlStrucks[Ids[i]].DwUin)
					if CurCnt == Cnt {
						return ret
					}
				}

			}
		}
		Loops += 1
		if Loops == 3 {
			break
		}
	}

	return ret
}

func (p *PlayerProfileManager) ReqUpdateFBPicURL(args []interface{}) {
	a := args[0].(gate.Agent)
	play, _ := internal.Agents[a]
	buf := args[1].([]byte)
	player := play.(*Player)

	req := &msg.ReqUpdateFBPicURL{}
	res := &msg.ResUpdateFBPicURL{}
	proto.Unmarshal(buf, req)
	profile := p.GetPlayerProfile(player.M_DwUin)
	res.ResultCode = 0
	if profile != nil {
		profile.PicURL = req.URL
		p.UpdateNewProfile(profile)
	} else {
		st := db.SqlPlayerProfileStruct{}
		st.DwUin = player.M_DwUin
		st.ImageFrame = 1
		st.ImageIcon = 1
		st.UnlockFrame = ""
		st.UnlockIcon = ""
		st.PicURL = req.URL
		st.NickName = "Player" + strconv.Itoa(int(player.M_DwUin))
		p.UpdateNewProfile(&st)
	}
	agent := player.GetAgentByPlayer()
	data1, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResUpdateFBPicURL", data1)

}

func (p *PlayerProfileManager) NewGetPlayerProfile(DwUin int32) *db.SqlPlayerProfileStruct {
	profile := p.GetPlayerProfile(DwUin)
	if profile != nil {
		return profile
	} else {
		st := db.SqlPlayerProfileStruct{}
		st.DwUin = DwUin
		st.ImageFrame = 1
		st.ImageIcon = 1
		st.UnlockFrame = ""
		st.UnlockIcon = ""
		st.PicURL = ""
		st.NickName = "Player" + strconv.Itoa(int(DwUin))
		p.UpdateNewProfile(&st)
		return &st
	}
}
